package com.heima.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.heima.api.schedule.WemediaFeign;
import com.heima.common.constants.CommonConstants;
import com.heima.common.exception.CustomException;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.dtos.UserRelationDto;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.user.pojos.ApUserFan;
import com.heima.model.user.pojos.ApUserFollow;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.user.mapper.ApUserFanMapper;
import com.heima.user.mapper.ApUserFollowMapper;
import com.heima.user.mapper.ApUserMapper;
import com.heima.user.service.IApUserFollowService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.utils.common.WmThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * APP用户关注信息表 服务实现类
 * </p>
 *
 * @author fkn
 * @since 2024-08-21
 */
@Service
public class ApUserFollowServiceImpl extends ServiceImpl<ApUserFollowMapper, ApUserFollow> implements IApUserFollowService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private ApUserMapper userMapper;
    @Resource
    private ApUserFanMapper apUserFanMapper;

    @Autowired
    private WemediaFeign wemediaFeign;

    private final static String USER_FOLLOW_IDEMPOTENT = "USER_FOLLOW_IDEMPOTENT";
    private final static String USER_NOT_FOLLOW_IDEMPOTENT = "USER_NOT_FOLLOW_IDEMPOTENT";

    @Override
    @Transactional
    public ResponseResult userFollow(UserRelationDto dto) {
        ValueOperations<String, String> operation = stringRedisTemplate.opsForValue();
        //获取当前用户ID
        Integer userId = WmThreadLocalUtil.getUser().getApUserId();
        //幂等性
        if (!operation.setIfAbsent(USER_FOLLOW_IDEMPOTENT + userId,"1",1, TimeUnit.SECONDS)){
            throw new CustomException(AppHttpCodeEnum.NOT_REPETITION_OPERATION);
        }
        //查询作者姓名
        Integer authorId = dto.getAuthorId();

        ApUser user = userMapper.selectById(userId);
        ApUser apUser = userMapper.selectById(authorId);
        //填充关注表pojo
        LocalDateTime now = LocalDateTime.now();
        ApUserFollow apUserFollow = ApUserFollow.builder().userId(userId).followId(authorId)
                .followName(apUser.getName()).level(ApUserFollow.level.USUALLY.getCode())
                .isNotice(CommonConstants.IS).createdTime(now).build();
        //插入关注表数据库
        save(apUserFollow);

        //填充粉丝表pojo
        ApUserFan apUserFan = ApUserFan.builder().userId(authorId).fansId(userId)
                .fansName(user.getName()).level(ApUserFan.level.USUALLY.getCode())
                .createdTime(now).isDisplay(CommonConstants.IS)
                .isShieldLetter(CommonConstants.NOT).isShieldComment(CommonConstants.NOT).build();
        apUserFanMapper.insert(apUserFan);
        return ResponseResult.okResult(null);
    }

    @Override
    @Transactional
    public ResponseResult userNotFollow(UserRelationDto dto) {
        ValueOperations<String, String> operation = stringRedisTemplate.opsForValue();
        //获取当前用户ID
        Integer apUserId = WmThreadLocalUtil.getUser().getApUserId();
        //幂等性
        if (!operation.setIfAbsent(USER_NOT_FOLLOW_IDEMPOTENT + apUserId,"1",1, TimeUnit.SECONDS)){
            throw new CustomException(AppHttpCodeEnum.NOT_REPETITION_OPERATION);
        }
        //获取作者ID
        int authorId = dto.getAuthorId();
        LambdaQueryWrapper<ApUserFollow> conditionFollow = new LambdaQueryWrapper<ApUserFollow>()
                .eq(ApUserFollow::getUserId, apUserId)
                .eq(ApUserFollow::getFollowId, authorId);
        remove(conditionFollow);
        LambdaQueryWrapper<ApUserFan> conditionFans = new LambdaQueryWrapper<ApUserFan>()
                .eq(ApUserFan::getUserId, authorId)
                .eq(ApUserFan::getFansId, apUserId);
        apUserFanMapper.delete(conditionFans);
        return ResponseResult.okResult(null);
    }
}
